﻿using System;
using UniRx.InternalUtil;

namespace UniRx.Operators
{
	// Token: 0x02000243 RID: 579
	internal class AmbObservable<T> : OperatorObservableBase<T>
	{
		// Token: 0x06000D6E RID: 3438 RVA: 0x0003FDFC File Offset: 0x0003E1FC
		public AmbObservable(IObservable<T> source, IObservable<T> second) : base(source.IsRequiredSubscribeOnCurrentThread<T>() || second.IsRequiredSubscribeOnCurrentThread<T>())
		{
			this.source = source;
			this.second = second;
		}

		// Token: 0x06000D6F RID: 3439 RVA: 0x0003FE26 File Offset: 0x0003E226
		protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
		{
			return new AmbObservable<T>.AmbOuterObserver(this, observer, cancel).Run();
		}

		// Token: 0x04000796 RID: 1942
		private readonly IObservable<T> source;

		// Token: 0x04000797 RID: 1943
		private readonly IObservable<T> second;

		// Token: 0x02000244 RID: 580
		private class AmbOuterObserver : OperatorObserverBase<T, T>
		{
			// Token: 0x06000D70 RID: 3440 RVA: 0x0003FE35 File Offset: 0x0003E235
			public AmbOuterObserver(AmbObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
			{
				this.parent = parent;
			}

			// Token: 0x06000D71 RID: 3441 RVA: 0x0003FE58 File Offset: 0x0003E258
			public IDisposable Run()
			{
				this.leftSubscription = new SingleAssignmentDisposable();
				this.rightSubscription = new SingleAssignmentDisposable();
				ICancelable cancelable = StableCompositeDisposable.Create(this.leftSubscription, this.rightSubscription);
				AmbObservable<T>.AmbOuterObserver.Amb amb = new AmbObservable<T>.AmbOuterObserver.Amb();
				amb.targetDisposable = cancelable;
				amb.targetObserver = new AmbObservable<T>.AmbOuterObserver.AmbDecisionObserver(this, AmbObservable<T>.AmbOuterObserver.AmbState.Left, this.rightSubscription, amb);
				AmbObservable<T>.AmbOuterObserver.Amb amb2 = new AmbObservable<T>.AmbOuterObserver.Amb();
				amb2.targetDisposable = cancelable;
				amb2.targetObserver = new AmbObservable<T>.AmbOuterObserver.AmbDecisionObserver(this, AmbObservable<T>.AmbOuterObserver.AmbState.Right, this.leftSubscription, amb2);
				this.leftSubscription.Disposable = this.parent.source.Subscribe(amb);
				this.rightSubscription.Disposable = this.parent.second.Subscribe(amb2);
				return cancelable;
			}

			// Token: 0x06000D72 RID: 3442 RVA: 0x0003FF08 File Offset: 0x0003E308
			public override void OnNext(T value)
			{
			}

			// Token: 0x06000D73 RID: 3443 RVA: 0x0003FF0A File Offset: 0x0003E30A
			public override void OnError(Exception error)
			{
			}

			// Token: 0x06000D74 RID: 3444 RVA: 0x0003FF0C File Offset: 0x0003E30C
			public override void OnCompleted()
			{
			}

			// Token: 0x04000798 RID: 1944
			private readonly AmbObservable<T> parent;

			// Token: 0x04000799 RID: 1945
			private readonly object gate = new object();

			// Token: 0x0400079A RID: 1946
			private SingleAssignmentDisposable leftSubscription;

			// Token: 0x0400079B RID: 1947
			private SingleAssignmentDisposable rightSubscription;

			// Token: 0x0400079C RID: 1948
			private AmbObservable<T>.AmbOuterObserver.AmbState choice = AmbObservable<T>.AmbOuterObserver.AmbState.Neither;

			// Token: 0x02000245 RID: 581
			private enum AmbState
			{
				// Token: 0x0400079E RID: 1950
				Left,
				// Token: 0x0400079F RID: 1951
				Right,
				// Token: 0x040007A0 RID: 1952
				Neither
			}

			// Token: 0x02000246 RID: 582
			private class Amb : IObserver<T>
			{
				// Token: 0x06000D76 RID: 3446 RVA: 0x0003FF16 File Offset: 0x0003E316
				public void OnNext(T value)
				{
					this.targetObserver.OnNext(value);
				}

				// Token: 0x06000D77 RID: 3447 RVA: 0x0003FF24 File Offset: 0x0003E324
				public void OnError(Exception error)
				{
					try
					{
						this.targetObserver.OnError(error);
					}
					finally
					{
						this.targetObserver = EmptyObserver<T>.Instance;
						this.targetDisposable.Dispose();
					}
				}

				// Token: 0x06000D78 RID: 3448 RVA: 0x0003FF6C File Offset: 0x0003E36C
				public void OnCompleted()
				{
					try
					{
						this.targetObserver.OnCompleted();
					}
					finally
					{
						this.targetObserver = EmptyObserver<T>.Instance;
						this.targetDisposable.Dispose();
					}
				}

				// Token: 0x040007A1 RID: 1953
				public IObserver<T> targetObserver;

				// Token: 0x040007A2 RID: 1954
				public IDisposable targetDisposable;
			}

			// Token: 0x02000247 RID: 583
			private class AmbDecisionObserver : IObserver<T>
			{
				// Token: 0x06000D79 RID: 3449 RVA: 0x0003FFB0 File Offset: 0x0003E3B0
				public AmbDecisionObserver(AmbObservable<T>.AmbOuterObserver parent, AmbObservable<T>.AmbOuterObserver.AmbState me, IDisposable otherSubscription, AmbObservable<T>.AmbOuterObserver.Amb self)
				{
					this.parent = parent;
					this.me = me;
					this.otherSubscription = otherSubscription;
					this.self = self;
				}

				// Token: 0x06000D7A RID: 3450 RVA: 0x0003FFD8 File Offset: 0x0003E3D8
				public void OnNext(T value)
				{
					object gate = this.parent.gate;
					lock (gate)
					{
						if (this.parent.choice == AmbObservable<T>.AmbOuterObserver.AmbState.Neither)
						{
							this.parent.choice = this.me;
							this.otherSubscription.Dispose();
							this.self.targetObserver = this.parent.observer;
						}
						if (this.parent.choice == this.me)
						{
							this.self.targetObserver.OnNext(value);
						}
					}
				}

				// Token: 0x06000D7B RID: 3451 RVA: 0x00040080 File Offset: 0x0003E480
				public void OnError(Exception error)
				{
					object gate = this.parent.gate;
					lock (gate)
					{
						if (this.parent.choice == AmbObservable<T>.AmbOuterObserver.AmbState.Neither)
						{
							this.parent.choice = this.me;
							this.otherSubscription.Dispose();
							this.self.targetObserver = this.parent.observer;
						}
						if (this.parent.choice == this.me)
						{
							this.self.targetObserver.OnError(error);
						}
					}
				}

				// Token: 0x06000D7C RID: 3452 RVA: 0x00040128 File Offset: 0x0003E528
				public void OnCompleted()
				{
					object gate = this.parent.gate;
					lock (gate)
					{
						if (this.parent.choice == AmbObservable<T>.AmbOuterObserver.AmbState.Neither)
						{
							this.parent.choice = this.me;
							this.otherSubscription.Dispose();
							this.self.targetObserver = this.parent.observer;
						}
						if (this.parent.choice == this.me)
						{
							this.self.targetObserver.OnCompleted();
						}
					}
				}

				// Token: 0x040007A3 RID: 1955
				private readonly AmbObservable<T>.AmbOuterObserver parent;

				// Token: 0x040007A4 RID: 1956
				private readonly AmbObservable<T>.AmbOuterObserver.AmbState me;

				// Token: 0x040007A5 RID: 1957
				private readonly IDisposable otherSubscription;

				// Token: 0x040007A6 RID: 1958
				private readonly AmbObservable<T>.AmbOuterObserver.Amb self;
			}
		}
	}
}
